package pl;

import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;

public class ElementaryFile extends CardFile {

	private short fileSize;
	private byte[] fileContent;

	public SecurityConditionByte read;
	public SecurityConditionByte update;
	
	public ElementaryFile(byte[] fid, byte efType, byte[] size, byte[] access) 
	{
		super(fid, access);
				
		// access conditions
		setAccessConditions(access);
		
		fciTemplate = new byte[(short)(2 + fid.length + 2 + 2 + 3 + 2 + 2 + access.length)];
		
		this.setFileDescriptorByte((byte)0x01);
		
		switch ((short)efType)
		{
			case 0x01:
				fileContent = new byte[MediatorFE.byteArrayToShort(size)];
				setFileSize((short)fileContent.length);
				break;
			default:
				break; // throw exception
		}
	}

	public void setAccessConditions(byte[] acBytes) {
		
		byte bytes = acBytes[0];
		
		if (bytes > 0)
		{
			// READ BINARY
			if ((bytes & 0x01)== 0x01)
			{
				read = new SecurityConditionByte(acBytes[1]); 
			}
			else // empty -> 
			{
				read = new SecurityConditionByte((byte) 0x00); 
			}
			
			// UPDATE BINARY
			if ((bytes & 0x02)== 0x02)
			{
				update = new SecurityConditionByte(acBytes[2]); 
			}
			else 
			{
				update = new SecurityConditionByte((byte) 0x00); 
			}
			
/*			// WRITE BINARY
			if ((bytes & 0x04)== 0x04)
			{
				update = new SecurityConditionByte(acBytes[3]); 
			}*/
		}
		else
		{
			ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
		}
		
		
		/*
		b8 b7 b6 b5 b4 b3 b2 b1 Meaning 
		0 - - - - - - - Bits 7 to 1 according to this table 
		1 - - - - - - - Bits 3 to 1 according to this table (bits 7 to 4 proprietary) 
		0 1 - - - - - -  DELETE FILE
		0 - 1 - - - - -  TERMINATE EF
		0 - - 1 - - - -  ACTIVATE FILE
		0 - - - 1 - - -  DEACTIVATE FILE
		- - - - - 1 - -  WRITE BINARY, WRITE RECORD, APPEND RECORD
		- - - - - - 1 -  UPDATE BINARY, UPDATE RECORD, ERASE BINARY, ERASE RECORD (S) 
		- - - - - - - 1  READ BINARY, READ RECORD (S), SEARCH BINARY, SEARCH RECORD
		*/
		
		// READ

		// acBytes[0] -> length
	
	}
	
	private void setFileSize(short fileSize) {
		this.fileSize = fileSize;
	}

	private short getFileSize() {
		return fileSize;
	}

	public void setFileContent(byte[] inBuff, short offset) {

		if (((short)(fileContent.length - offset)) >=  (short)inBuff.length)
		{
			Util.arrayCopy(inBuff, (short)0, fileContent, offset, (short)inBuff.length);
		}
		else 
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
			
	}

	public byte[] getFileContent(byte[] outBuff, short offset, short le) {
		
		if (le > (short)fileContent.length) 
		{
			outBuff = JCSystem.makeTransientByteArray((short)fileContent.length, JCSystem.CLEAR_ON_DESELECT);
			le = (short)fileContent.length;
		}
		
		Util.arrayCopy(fileContent, offset, outBuff, (short)0, le);
		return fileContent;
	}
	
    public byte[] getFileContent(short offset, short le) {
    	
    	if (le > (short)fileContent.length) le = (short)fileContent.length;
    	byte[] outBuff = JCSystem.makeTransientByteArray((short)le, JCSystem.CLEAR_ON_DESELECT);
		Util.arrayCopy(fileContent, offset, outBuff, (short)0, (short)le);	
		return outBuff;
	}
	
	public byte[] getFciTemplate()
	{
		fci.constructFciforEf(fciTemplate, this.getFid(), this.getFileSize(), this.AccessCondtions);
		return fciTemplate;
	}

}
